/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2008-2011, Salzburg Research. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 * - Neither the name of the KiWi Project nor the names of its contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * Contributor(s):
 * tkurz
 *
 * File Info:
 * User: tkurz
 * Date: 2011/01/19
 * Time: 10:55
 *
 * Project: KiWi2, kiwi-core module
 */

package kiwi.core.services.io;

import kiwi.core.api.config.ConfigurationService;
import kiwi.core.api.io.KiWiSerializer;
import kiwi.core.model.rdf.KiWiTriple;
import org.slf4j.Logger;

import javax.inject.Inject;
import java.io.*;
import java.util.*;

/**
 * The KiWi RdfJsonSerializer takes as argument a collection of triples and serialises them in the
 * HTML format (a simple table representation)
 * User: Thomas Kurz
 * Date: 19.01.11
 * Time: 10:55
 */
public class RdfHtmlSerializer implements KiWiSerializer {

	private static final String STYLE =	"#header{" +
										"	width:100%;" +
										"	height:20px;" +
										"}.subheader h3{" +
										"	margin:15px 0pt 0px;" +
										"	color:#006D8F;" +
										"}table{" +
										"	width:100%" +
										"}.trClassHeader{" +
										"	background-color:#006D8F;" +
										"	color:white;" +
										"}.trClass0{" +
										"	background-color:#DFF7FF" +
										"}.trClass1{" +
										"	background-color:lightblue;" +
										"}";

	@Inject
    private Logger log;

	@Inject
    private ConfigurationService configurationService;

		private static final List<String> MIMETYPES;
	static {
		MIMETYPES = new ArrayList<String>();
		MIMETYPES.add("text/html");
	}

	@Override
	public List<String> getProducedFormats() {
		return MIMETYPES;
	}

	@Override
	public String serializeTriples(Iterable<KiWiTriple> triples) {
		try {
		   	StringWriter writer = new StringWriter();
			serializeTriples(triples,writer);
			return writer.toString();
		} catch(IOException e) {
			log.error("IO exception while writing output stream",e);
			return null;
		}
	}

	@Override
	public void serializeTriples(Iterable<KiWiTriple> triples, OutputStream out) throws IOException {
		Writer writer = new BufferedWriter(new OutputStreamWriter(out));
		serializeTriples(triples,writer);
	}

	@Override
	public void serializeTriples(Iterable<KiWiTriple> triples, Writer writer) throws IOException {
		writer.append("<html><head><title>Resources in HTML</title>");
		writer.append("<style type='text/css'>"+STYLE+"</style>");
		writer.append("</head><body>");

		//order by subject
		Map<Long,SortedSet<KiWiTriple>> tripleMap = new HashMap<Long,SortedSet<KiWiTriple>>();
		for( KiWiTriple triple : triples ) {
			if(tripleMap.containsKey(triple.getSubject().getId())) {
				SortedSet<KiWiTriple> ts = tripleMap.get(triple.getSubject().getId());
				ts.add(triple);
			} else {
				SortedSet<KiWiTriple> ts = new TreeSet<KiWiTriple>(new Comparator<KiWiTriple>() {
					public int compare(KiWiTriple o1, KiWiTriple o2) {
						if(o1.getProperty().toString().equals(o2.getProperty().toString())) return -1;
						return o1.getProperty().toString().compareTo(o2.getProperty().toString());
					}
				});
				ts.add(triple);
				tripleMap.put(triple.getSubject().getId(),ts);
			}
		}

		//header
		writer.append("<div id='header'><h2>KiWi2 Linked Data Explorer</h2></div>");
		//check if there are triples
		if(tripleMap.isEmpty()) {
			writer.append("<div class='subheader'><h3>No triples to display!</h3></div>");
		}

		//subjects
		for(Long id : tripleMap.keySet()) {
			SortedSet<KiWiTriple> ts = tripleMap.get(id);

			//single subject
			int n = 0;
			for(KiWiTriple t : ts) {
				if(n==0) {
					//write header row
					writer.append("<div class='subheader'><h3>Description of "+t.getSubject().toString()+":</h3></div>");
					writer.append("<table><tr class='trClassHeader'><td>property</td><td>has value</td></tr>");
				}

				//write body rows
				String property = "<a href='"+t.getProperty().toString()+"'>"+t.getProperty().toString()+"</a>";
				String value;
				if( t.getObject().isUriResource() ) {
					value = "<a href='"+t.getObject().toString()+"'>"+t.getObject().toString()+"</a>";
				} else {
					value = t.getObject().toString();
				}

				writer.append("<tr class='trClass"+n%2+"'><td>"+property+"</td><td>"+value+"</td></tr>");

				n++;
				if( n==ts.size() ) {
					writer.append("</table>");
				}
			}
		}

		writer.append("</body></html>");
	}
}
